//
// See the file COPYING for redistribution information.
//

#include <stdint.h>
#include <Naipax/Common.hpp>
#include <Naipax/Error.hpp>
#include <Naipax/Fnv.hpp>
#include <Naipax/Digest.hpp>

using namespace std;
using namespace Naipax;

void Digest::Make(const string &rData, char *pDigest) {
    if (pDigest == NULL) {
        NAIPAX_THROW(Error::INVALID_ARGUMENT);
    }

    Naipax::Internal::Fnv::Hash128(rData.data(),
                                   rData.length(), (void*) pDigest);
}

void Digest::MakeAscii(const string &rData, char *pAsciiDigest) {
    if (pAsciiDigest == NULL) {
        NAIPAX_THROW(Error::INVALID_ARGUMENT);
    }

    char Digest[DIGEST_SIZE];

    Naipax::Internal::Fnv::Hash128(rData.data(),
                                   rData.length(), (void*) Digest);
    Digest::BinaryToAscii(Digest, pAsciiDigest);
}

void Digest::BinaryToAscii(const char *pDigest, char *pAsciiDigest) {
    if (pDigest == NULL || pAsciiDigest == NULL) {
        NAIPAX_THROW(Error::INVALID_ARGUMENT);
    }

    pAsciiDigest[DIGEST_ASCII_SIZE - 1] = '\0';
    for (uint32_t i = 0; i < DIGEST_SIZE; ++i) {
        uint8_t Low = pDigest[i] & 0x0f;
        pAsciiDigest[i*2+1] = (Low < 10 ? Low + '0' : Low + 'a' - 10);

        uint8_t High = (pDigest[i] & 0xf0) >> 4;
        pAsciiDigest[i*2] = (High < 10 ? High + '0' : High + 'a' - 10);
    }
}
